package com.palm.easy.service;

import com.palm.easy.domain.Service;
import com.palm.easy.domain.ServiceFoundItem;
import com.palm.easy.domain.ServiceItem;
import com.palm.easy.util.StringUtil;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.core.Aop;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ServerManageService {
    // private String localhost;
    Map<String, Server> servers = new ConcurrentHashMap<>();

    @Init
    public void regSelf() {
        Aop.getAsyn(Server.class, bw -> {
            Server server = bw.get();
            regServer(server.host(), bw.get());
        });
    }

    public boolean regServer(String name, Server server) {
        if (servers.containsKey(name)) {
            return false;
        }
        servers.put(name, server);
        return true;
    }

    public void remove(String name) {
        servers.remove(name);
    }

    public Set<String> serverNames() {
        return servers.keySet();
    }

    public Server getServer(String name) {
        if (StringUtil.isEmpty(name)) {
            return null;
        }
        return servers.get(name);
    }

    //列出所有服务
    public List<Service> listServices() {
        List<Service> services = new ArrayList<>();
        for (Map.Entry<String, Server> se : this.servers.entrySet()) {
            Server s = se.getValue();
            String host = se.getKey();
            Collection<Service> serverServers = s.listService();
            for (Service sv : serverServers) {
                sv.setServer(host);
                services.add(sv);
            }
        }
        return services;
    }

    public void delService(Service service) {
        Server server = servers.get(service.getServer());
        if (server == null) {
            throw new RuntimeException("sever错误");
        }
        server.deleteService(service);
    }

    public Collection<ServiceItem> serviceItemList() {
        Map<String, ServiceItem> serviceItemMap = new HashMap<>();
        for (Service service : listServices()) {
            if (!service.isEnabled()) {
                continue;
            }
            if (!service.isMapping() && !service.isFound()) {
                continue;
            }
            String sn = service.getServiceName();
            ServiceItem sit = serviceItemMap.get(sn);
            if (sit == null) {
                sit = new ServiceItem(sn);
                serviceItemMap.put(sn, sit);
            }
            if (StringUtil.isEmpty(sit.getMappingConfig())) {
                sit.setMappingConfig(service.getMappingSetting());
            }
            if (service.isMapping()) {
                if ("url".equals(service.getType())) {
                    String url = service.getUrl();
                    try {
                        URL u = new URL(url);
                        sit.setProtocol(u.getProtocol());
                        sit.setMappingPath(u.getPath());
                        int port=u.getPort();
                        if(port>0){
                            sit.getMappingServers().add(u.getHost() + ":" + u.getPort());
                        }else{
                            sit.getMappingServers().add(u.getHost());
                        }

                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                } else {
                    if (StringUtil.isEmpty(sit.getMappingPath())) {
                        sit.setMappingPath(service.getMappingPath());
                    }
                    String server = service.getServer() + ":" + service.getPort();
                    sit.getMappingServers().add(server);
                }
            }
            if (service.isFound()) {
                String url=service.getUrl();
                if ("url".equals(service.getType())) {
                    sit.getUrls().add(url);
                } else {
                    String contextPath=service.getContextPath();
                    if(contextPath.startsWith("http://")||contextPath.startsWith("https://")){
                        sit.getUrls().add(contextPath);
                    }else{
                        String address = "http://" + service.getServer() + ":" + service.getPort();
                        if (StringUtil.isNotEmpty(service.getContextPath())) {
                            address = address + service.getContextPath();
                        }
                        sit.getUrls().add(address);
                    }

                }

            }
        }
        return serviceItemMap.values();
    }
    public Collection<ServiceFoundItem> foundServices() {
        Map<String, ServiceFoundItem> serviceItemMap = new HashMap<>();
        for (Service service : listServices()) {
            if (!service.isEnabled()) {
                continue;
            }
            if (!service.isFound()) {
                continue;
            }
            String sn = service.getServiceName();
            ServiceFoundItem sit = serviceItemMap.get(sn);
            if (sit == null) {
                sit = new ServiceFoundItem();
                sit.setName(sn);
                sit.setTitle(service.getTitle());
                serviceItemMap.put(sn, sit);
            }
            if ("url".equals(service.getType())) {
                sit.getUrls().add(service.getUrl());
            } else {
                String contextPath=service.getContextPath();
                if(StringUtil.isEmpty(contextPath)){
                    contextPath="/";
                }
                if(contextPath.startsWith("http://")||contextPath.startsWith("https://")){
                    sit.getUrls().add(contextPath);
                }else{
                    String address = "http://" + service.getServer() + ":" + service.getPort();
                    if (StringUtil.isNotEmpty(service.getContextPath())) {
                        address = address + service.getContextPath();
                    }
                    sit.getUrls().add(address);
                }
            }
        }
        return serviceItemMap.values();
    }
}
